Dansk

Frigør potentialet i GraphQL Federation med Schema Stitching. Lær at bygge en samlet GraphQL API fra flere services, hvilket forbedrer skalerbarhed og vedligeholdelse.

GraphQL Federation: Schema Stitching - En Omfattende Guide

I det konstant udviklende landskab af moderne applikationsudvikling er behovet for skalerbare og vedligeholdelsesvenlige arkitekturer blevet altafgørende. Microservices, med deres iboende modularitet og uafhængige deployerbarhed, er blevet en populær løsning. Men at administrere talrige microservices kan introducere kompleksitet, især når det kommer til at eksponere en samlet API til klientapplikationer. Det er her, GraphQL Federation, og specifikt Schema Stitching, kommer ind i billedet.

Hvad er GraphQL Federation?

GraphQL Federation er en kraftfuld arkitektur, der giver dig mulighed for at bygge en enkelt, samlet GraphQL API fra flere underliggende GraphQL-tjenester (ofte repræsenterende microservices). Det gør det muligt for udviklere at forespørge data på tværs af forskellige tjenester, som om det var en enkelt graf, hvilket forenkler klientoplevelsen og reducerer behovet for kompleks orkestreringslogik på klientsiden.

Der er to primære tilgange til GraphQL Federation:

Denne artikel fokuserer på Schema Stitching og udforsker dens koncepter, fordele, begrænsninger og praktiske implementering.

Forståelse af Schema Stitching

Schema Stitching er processen med at flette flere GraphQL-skemaer sammen til et enkelt, sammenhængende skema. Dette samlede skema fungerer som en facade, der skjuler kompleksiteten af de underliggende tjenester for klienten. Når en klient sender en anmodning til det sammensyede skema, dirigerer gatewayen intelligent anmodningen til den eller de relevante underliggende tjenester, henter dataene og kombinerer resultaterne, før de returneres til klienten.

Tænk på det sådan her: Du har flere restauranter (tjenester), der hver især specialiserer sig i forskellige køkkener. Schema Stitching er som en universel menu, der kombinerer alle retterne fra hver restaurant. Når en kunde (klient) bestiller fra den universelle menu, bliver ordren intelligent dirigeret til de relevante restaurantkøkkener, maden tilberedes og kombineres derefter til en enkelt levering til kunden.

Nøglekoncepter i Schema Stitching

Fordele ved Schema Stitching

Schema Stitching tilbyder flere overbevisende fordele for organisationer, der anvender en microservices-arkitektur:

Begrænsninger ved Schema Stitching

Selvom Schema Stitching tilbyder mange fordele, er det vigtigt at være opmærksom på dens begrænsninger:

Praktisk implementering af Schema Stitching

Lad os gennemgå et forenklet eksempel på, hvordan man implementerer Schema Stitching ved hjælp af Node.js og graphql-tools-biblioteket (et populært valg til schema stitching). Dette eksempel involverer to microservices: en brugertjeneste og en produkttjeneste.

1. Definer fjernskemaerne

Først skal du definere GraphQL-skemaerne for hver af fjerntjenesterne.

Brugertjeneste (user-service.js):


const { buildSchema } = require('graphql');

const userSchema = buildSchema(`
  type User {
    id: ID!
    name: String
    email: String
  }

  type Query {
    user(id: ID!): User
  }
`);

const users = [
  { id: '1', name: 'Alice Smith', email: 'alice@example.com' },
  { id: '2', name: 'Bob Johnson', email: 'bob@example.com' },
];

const userRoot = {
  user: (args) => users.find(user => user.id === args.id),
};

module.exports = {
  schema: userSchema,
  rootValue: userRoot,
};

Produkttjeneste (product-service.js):


const { buildSchema } = require('graphql');

const productSchema = buildSchema(`
  type Product {
    id: ID!
    name: String
    price: Float
    userId: ID!  # Fremmednøgle til brugertjeneste
  }

  type Query {
    product(id: ID!): Product
  }
`);

const products = [
  { id: '101', name: 'Laptop', price: 1200, userId: '1' },
  { id: '102', name: 'Smartphone', price: 800, userId: '2' },
];

const productRoot = {
  product: (args) => products.find(product => product.id === args.id),
};

module.exports = {
  schema: productSchema,
  rootValue: productRoot,
};

2. Opret gateway-tjenesten

Opret nu den gateway-tjeneste, der vil sy de to skemaer sammen.

Gateway-tjeneste (gateway.js):


const { stitchSchemas } = require('@graphql-tools/stitch');
const { makeRemoteExecutableSchema } = require('@graphql-tools/wrap');
const { graphqlHTTP } = require('express-graphql');
const express = require('express');
const { introspectSchema } = require('@graphql-tools/wrap');
const { printSchema } = require('graphql');
const fetch = require('node-fetch');

async function createRemoteSchema(uri) {
  const fetcher = async (params) => {
    const response = await fetch(uri, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(params),
    });
    return response.json();
  };

  const schema = await introspectSchema(fetcher);
  return makeRemoteExecutableSchema({
    schema,
    fetcher,
  });
}

async function main() {
  const userSchema = await createRemoteSchema('http://localhost:4001/graphql');
  const productSchema = await createRemoteSchema('http://localhost:4002/graphql');

  const stitchedSchema = stitchSchemas({
    subschemas: [
      { schema: userSchema },
      { schema: productSchema },
    ],
    typeDefs: `
      extend type Product {
        user: User
      }
    `,
    resolvers: {
      Product: {
        user: {
          selectionSet: `{ userId }`,
          resolve(product, args, context, info) {
            return info.mergeInfo.delegateToSchema({
              schema: userSchema,
              operation: 'query',
              fieldName: 'user',
              args: {
                id: product.userId,
              },
              context,
              info,
            });
          },
        },
      },
    },
  });

  const app = express();
  app.use('/graphql', graphqlHTTP({
    schema: stitchedSchema,
    graphiql: true,
  }));

  app.listen(4000, () => console.log('Gateway-server kører på http://localhost:4000/graphql'));
}

main().catch(console.error);

3. Kør tjenesterne

Du skal køre brugertjenesten og produkttjenesten på forskellige porte. For eksempel:

Brugertjeneste (port 4001):


const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { schema, rootValue } = require('./user-service');

const app = express();
app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: rootValue,
  graphiql: true,
}));

app.listen(4001, () => console.log('Brugertjeneste kører på http://localhost:4001/graphql'));

Produkttjeneste (port 4002):


const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { schema, rootValue } = require('./product-service');

const app = express();
app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: rootValue,
  graphiql: true,
}));

app.listen(4002, () => console.log('Produkttjeneste kører på http://localhost:4002/graphql'));

4. Forespørg det sammensyede skema

Nu kan du forespørge det sammensyede skema gennem gatewayen (der kører på port 4000). Du kan køre en forespørgsel som denne:


query {
  product(id: "101") {
    id
    name
    price
    user {
      id
      name
      email
    }
  }
}

Denne forespørgsel henter produktet med ID "101" og henter også den tilknyttede bruger fra brugertjenesten, hvilket demonstrerer, hvordan Schema Stitching giver dig mulighed for at forespørge data på tværs af flere tjenester i en enkelt anmodning.

Avancerede Schema Stitching-teknikker

Ud over det grundlæggende eksempel er her nogle avancerede teknikker, der kan bruges til at forbedre din Schema Stitching-implementering:

Valget mellem Schema Stitching og Apollo Federation

Selvom Schema Stitching er en levedygtig mulighed for GraphQL Federation, er Apollo Federation blevet det mere populære valg på grund af dens avancerede funktioner og forbedrede udvikleroplevelse. Her er en sammenligning af de to tilgange:

Funktion Schema Stitching Apollo Federation
Skemadefinition Bruger eksisterende GraphQL-skemasprog Bruger et deklarativt skemasprog med direktiver
Forespørgselsplanlægning Kræver manuel forespørgselsdelegering Automatisk forespørgselsplanlægning af Apollo Gateway
Typeudvidelser Begrænset understøttelse Indbygget understøttelse af typeudvidelser
Nøgledirektiver Ikke understøttet Bruger @key-direktivet til at identificere entiteter
Distribueret sporing Kræver manuel implementering Indbygget understøttelse af distribueret sporing
Værktøjer og økosystem Mindre modne værktøjer Mere modne værktøjer og et stort fællesskab
Kompleksitet Kan være komplekst at administrere i store systemer Designet til store og komplekse systemer

Hvornår skal man vælge Schema Stitching:

Hvornår skal man vælge Apollo Federation:

Eksempler og use cases fra den virkelige verden

Her er nogle eksempler fra den virkelige verden på, hvordan GraphQL Federation, herunder Schema Stitching, kan bruges:

Bedste praksis for Schema Stitching

For at sikre en vellykket implementering af Schema Stitching, følg disse bedste praksisser:

Konklusion

GraphQL Federation med Schema Stitching tilbyder en kraftfuld tilgang til at bygge samlede API'er fra flere tjenester i en microservices-arkitektur. Ved at forstå dens kernekoncepter, fordele, begrænsninger og implementeringsteknikker kan du udnytte Schema Stitching til at forenkle dataadgang, forbedre skalerbarhed og øge vedligeholdelsesvenligheden. Selvom Apollo Federation er kommet frem som en mere avanceret løsning, forbliver Schema Stitching en levedygtig mulighed for enklere scenarier, eller når eksisterende GraphQL-tjenester skal integreres. Overvej omhyggeligt dine specifikke behov og krav for at vælge den bedste tilgang for din organisation.